package cn.ecnu.service.impl;

import cn.ecnu.common.constant.BusinessConstant;
import cn.ecnu.mapper.*;
import cn.ecnu.pojo.*;
import cn.ecnu.service.ConsultantService;
import cn.ecnu.vo.fromFront.*;
import cn.ecnu.vo.toFront.ConsultantVo;
import cn.ecnu.vo.toFront.ConsultantWithFlagVo;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import java.util.*;

import static cn.ecnu.common.constant.BusinessConstant.ALIVE_KEY;
import static cn.ecnu.common.constant.BusinessConstant.CONSULTANT_DEFAULT_DUTY_KEY;

@Service
public class ConsultantServiceImpl implements ConsultantService {

    @Resource
    private RedisTemplate<Object, Object> redisTemplate;

    @Resource
    private ConsultRecordMapper consultRecordMapper;

    @Resource
    private HelpRecordMapper helpRecordMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private ConsultantMapper consultantMapper;

    @Resource
    private ConsultantSupervisorConnectorMapper connectorMapper;

    @Resource
    private SupervisorMapper supervisorMapper;


    @Override
    public boolean judgeOnline(Integer uid) {
        if (redisTemplate.hasKey(String.format(ALIVE_KEY, uid))) {
            return true;
        }
        return false;
    }

    @Override
    //原本只是一个咨询师的列表，现在要为每个咨询师加上一个是否咨询过的 flag
    public List<ConsultantWithFlagVo> consultantsAddFlag(List<ConsultantVo> consultants, Integer uid) {

        ArrayList<ConsultantWithFlagVo> result = new ArrayList<>();

        HashSet<Integer> historyConsultantIds = new HashSet<>();

        List<ConsultRecord> records = consultRecordMapper.getConsultRecordByVisitorId(uid);
        for (ConsultRecord record : records) {
            historyConsultantIds.add(record.getToId());
        }

        for (ConsultantVo consultant : consultants) {
            ConsultantWithFlagVo consultantWithFlagVo;
            if (historyConsultantIds.contains(consultant.getConsultantInfo().getConsultantId())) {
                consultantWithFlagVo = new ConsultantWithFlagVo(consultant, true);
            } else {
                consultantWithFlagVo = new ConsultantWithFlagVo(consultant, false);
            }
            result.add(consultantWithFlagVo);
        }

        return result;

    }

    // 请求帮助
    @Override
    public Map<String, Integer> startHelp(StartHelpVo vo) {
        HashMap<String, Integer> map = new HashMap<>();
        try {
            HelpRecord helpRecord = new HelpRecord();
            BeanUtils.copyProperties(vo, helpRecord);
            helpRecord.setDatetime(new Date());
            helpRecordMapper.insertHelpRecord(helpRecord);

            String key = String.format(BusinessConstant.SUPERVISOR_ONGOING_COUNT_KEY, vo.getToId()); // 获取一个key
            ValueOperations<Object, Object> opsForValue = redisTemplate.opsForValue();
            opsForValue.increment(key, 1);
            map.put("helpRecordId", helpRecord.getHelpRecordId());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    // 结束帮助
    @Override
    public void endHelp(EndHelpVo vo) {
        try {
            HelpRecord helpRecord = helpRecordMapper.getHelpRecordById(vo.getHelpRecordId());
            helpRecord.setDuration(vo.getDuration());
            helpRecordMapper.updateHelpRecordById(helpRecord);

            // 更新Supervisor信息
            Supervisor supervisor = supervisorMapper.getSupervisorById(helpRecord.getToId());
            supervisor.setCountTotal(supervisor.getCountTotal() + 1);
            supervisor.setTimeTotal(supervisor.getTimeTotal() + helpRecord.getDuration());
            supervisorMapper.updateSupervisor(supervisor);

            // 更新help_ongoing
            String key = String.format(BusinessConstant.SUPERVISOR_ONGOING_COUNT_KEY, helpRecord.getToId()); // 获取一个key
            ValueOperations<Object, Object> opsForValue = redisTemplate.opsForValue();
            opsForValue.decrement(key, 1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 评论访客
    @Override
    public void commentVisitor(CommentVisitorVo vo) {
        try {
            ConsultRecord consultRecord = consultRecordMapper.getConsultRecordById(vo.getConsultRecordId());
            consultRecord.setToDiagnosis(vo.getToDiagnosis());
            consultRecord.setToComment(vo.getToComment());
            consultRecordMapper.updateRecordById(consultRecord);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void addConsultant(ConsultantForm vo) {
        try {
            User user = new User();
            user.setRole(1);
            BeanUtils.copyProperties(vo, user); // 新增用户
            userMapper.insertUser(user);
            Consultant consultant = new Consultant();
            consultant.setConsultantId(user.getUserId());

            // 初始化操作
            consultant.setTimeTotal(0);
            consultant.setCountTotal(0);
            consultant.setConsultantGrade(5);
            consultantMapper.insertConsultant(consultant); // 新增咨询师


            vo.getSupervisorList().forEach((id) -> {
                ConsultantSupervisorConnector connector = new ConsultantSupervisorConnector();
                connector.setConsultantId(user.getUserId());
                connector.setSupervisorId(id);
                connectorMapper.insertConnector(connector); // 新增绑定关系
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void changeSupervisor(ChangeSupervisorVo vo) {
        try {
            connectorMapper.deleteAllBindingByConsultantId(vo.getUserId());
            vo.getSupervisors().forEach((id) -> {
                ConsultantSupervisorConnector connector = new ConsultantSupervisorConnector();
                connector.setConsultantId(vo.getUserId());
                connector.setSupervisorId(id);
                connectorMapper.insertConnector(connector);
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void changeDefaultDuty(ChangeDefaultDutyVo vo) {
        try {
            SetOperations<Object, Object> opsForSet = redisTemplate.opsForSet();
            for (int i = 1; i <= 7; i++) {
                if (BooleanUtils.isTrue(opsForSet.isMember(String.format(CONSULTANT_DEFAULT_DUTY_KEY, i), vo.getUserId()))) {
                    opsForSet.remove(String.format(CONSULTANT_DEFAULT_DUTY_KEY, i), vo.getUserId()); // 删除已有的排班
                }
            }

            vo.getDefaultDuty().forEach((day) -> {
                opsForSet.add(String.format(CONSULTANT_DEFAULT_DUTY_KEY, day), vo.getUserId());
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
